/**
YASTACS rendering system.

License: GNU General Public License

	YASTACS game
    Copyright (C) 2012 Kalman Kiss, kiskami@freemail.hu

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
	Contact author at: kiskami@freemail.hu or
					Hungary, 8900 Zalaegerszeg
					Kakukkfu u 4.
*/
module rendering.RenderSystem;

import std.stdio;
import std.conv;

import ogreint.Root;
import ogreint.RenderWindow;
import ogreint.SceneManager;
import ogreint.SceneType;
import ogreint.SceneNode;
import ogreint.Entity;
import ogreint.Light;
import ogreint.Vector3;
import ogreint.ColourValue;
import ogreint.Camera;
import ogreint.Viewport;
import ogreint.Math;

import ogreint.MiscFuncs;

// Fade in-out:
// http://www.ogre3d.org/tikiwiki/tiki-index.php?page=FadeEffectOverlay&structure=Cookbook

class RenderSystem {
public:
	
	this(string windowtitle, int w=640, int h=480, bool fullscreen=false) {
			debug writeln("Before Ogre init.");
			scope (exit) debug writeln("After Ogre init.");		

			debug {
				auto pluginsPath = "plugins_d.cfg"; 
				auto resourcesPath = "resources_d.cfg ";
			} else {
				auto pluginsPath = "plugins.cfg";
				auto resourcesPath = "resources.cfg ";
			}
			root = new Root(pluginsPath);

			// TODO: configuration
			Root.getSingleton().setRenderSystem(
				Root.getSingleton().getRenderSystemByName("Direct3D9 Rendering Subsystem"));

			locateResources(resourcesPath);
			loadResources();

			mWindow = Root.getSingleton().initialise(false);
			mWindow = Root.getSingleton().createRenderWindow(windowtitle, w, h, fullscreen);
			// TODO: determine best scenemanager scenetype
			mSceneMgr = Root.getSingleton().createSceneManager(SceneType.ST_EXTERIOR_CLOSE/*ST_EXTERIOR_FAR*//*ST_GENERIC*/, "yastacs"); 

			// Create the camera
			playerCam = mSceneMgr.createCamera("PlayerCam");

			// Position it at 500 in Z direction
			playerCam.setPosition(new Vector3(0,0,500));
			// Look back along -Z
			playerCam.lookAt(new Vector3(0,0,-1));
			playerCam.setNearClipDistance(5); 

			// Create one viewport, entire window
			playerCamVP = mWindow.addViewport(playerCam);
			playerCamVP.setBackgroundColour(new ColourValue(0,0,0));

			// Alter the camera aspect ratio to match the viewport
			playerCam.setAspectRatio(
										playerCamVP.getActualWidth()/ to!float(playerCamVP.getActualHeight()));


			setAmbientLight(new ColourValue(0.7,0.7,0.7));
	}

	@property RenderWindow renderwindow() { return mWindow; }

	Camera createCamera(string name) {
		return mSceneMgr.createCamera(name);
	}

	void Update() {
		Root.getSingleton().renderOneFrame();
	}

	void setSkyBox(string mat_name) {
		mSceneMgr.setSkyBox(true, mat_name);
	}

	Camera getCamera() { return playerCam; }

	SceneNode getRootSceneNode() { return mSceneMgr.getRootSceneNode(); }

	SceneNode createSceneNode(string name) {
		return mSceneMgr.createSceneNode(name);
	}

	Entity createEntity(string entityName, string meshName) {
		return mSceneMgr.createEntity(entityName, meshName);
	}

	Light createLight(string name) {
		return mSceneMgr.createLight(name);
	}

	void setAmbientLight(ColourValue colour) {
		mSceneMgr.setAmbientLight(colour);
	}

	string screenshotToFile() {
		return mWindow.writeContentsToTimestampedFile("yatacs-screenshot-",".png");
	}

private:

	RenderWindow mWindow;
	SceneManager mSceneMgr;
	Camera playerCam;

	Viewport playerCamVP;

	Root root;
}
